package com.summer.guardedSuspension;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;

public class AlarmAgent {
	private volatile boolean connectedToService = false;
	
	private final Predicate agentConnected = new Predicate(){
		public boolean evaluate() {
			return connectedToService;
		}
	};
	
	private final Blocker blocker = new ConditionVarBlocker();
	
	private final Timer heartbeatTimer = new Timer(true); 
	
	public void sendAlarm(final AlarmInfo alarm) throws Exception{
		GuardedAction<Void> guardedAction = new GuardedAction<Void>(agentConnected) {

			public Void call() throws Exception {
				doSendAlarm(alarm);
				return null;
			}
		};
		
		blocker.callWithGuard(guardedAction);
	}
	
	private void doSendAlarm(AlarmInfo alarm){
		try{
			Thread.sleep(50);
		}catch(InterruptedException ex){
		}
	}
	
	public void init(){
		Thread connectingThread = new Thread(new ConnectingTask());
		connectingThread.start();
		heartbeatTimer.schedule(new HeartbeatTask(), 60000,2000);
	}
	
	public void disconnect(){
		connectedToService = false;
	}
	
	protected void onConnected(){
		try{
			blocker.signalAfter(new Callable<Boolean>() {
				public Boolean call() throws Exception {
					connectedToService = true;
					return Boolean.TRUE;
				}
			});
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	protected void onDisconnected() {
		connectedToService = false;
	}
	
	private class ConnectingTask implements Runnable{
		public void run() {
			try{
				Thread.sleep(100);
			}catch(InterruptedException ex){
			}
			onConnected();
		}
	}
	
	private class HeartbeatTask extends TimerTask{
		@Override
		public void run() {
			if(!testConnection()){
				onDisconnected();
				reconnect();
			}
		}
		
		private boolean testConnection(){
			return true;
		}
		
		private void reconnect(){
			ConnectingTask connectingThread = new ConnectingTask();
			connectingThread.run();
		}
	}
	
	private class AlarmInfo{
		
	}
}
